#include<iostream>
#include<assert.h>
#include"R_iterator.h"
using namespace MyRI;
using std::ostream;
using std::istream;
namespace MyV{
  template<class T>
  class vector
  {
  public:
    typedef T* iterator;
    typedef const T* const_iterator;
    typedef Reverse_Iterator<T,iterator> reverse_iterator; 
    typedef Reverse_Iterator<T,const_iterator> const_reverse_iterator;
    vector():
      _start(nullptr),
      _finish(nullptr),
      _endofstoage(nullptr) {}
    template<class InPutIterator>
    vector(InPutIterator frist,InPutIterator last):
      _start(new T[last - frist -1]),
      _finish(nullptr),
      _endofstoage(nullptr)
    {
      _finish = _start;
      while(frist != last)
      {
        *(_finish++) = *(frist++);
      }
      _endofstoage = _finish;
    }
    vector(size_t n,const T& x = T())
      :_start(nullptr),
      _finish(nullptr),
      _endofstoage(nullptr)
    {
      reserve(n);
      for(size_t i = 0;i<n;i++)
      {
        push_back(x);
      }
    }
    vector(int n,const T& x = T())
      :_start(nullptr),
      _finish(nullptr),
      _endofstoage(nullptr)
    {
      reserve(n);
      for(size_t i = 0;i<n;i++)
      {
        push_back(x);
      }
    }
    vector(const vector& v):
      _start(nullptr),
      _finish(nullptr),
      _endofstoage(nullptr)
    {
      vector tmp(v.begin(),v.end());
      swap(tmp);
     // size_t size = v._finish - v._start;
     // _start = _finish = new T[size];
     // for(auto it : v)
     // {
     //   *(_finish++) = it;
     // }
     // _endofstoage = _finish;
    }
    void swap(vector& v)
    {
      //iterator copy_start = v._start,copy_finish = v._finish,copy_endofstoage = v.endofstoage; 
      //v._start = _start;
      //v._finish = _finish;
      //v.endofstoage = _endofstoage;
      //_start = copy_start;
      //_finish = copy_finish;
      //_endofstoage = copy_endofstoage;
      std::swap(_start,v._start);
      std::swap(_finish,v._finish);
      std::swap(_endofstoage,v._endofstoage);
    }
    vector& operator=(vector v)
    {
      swap(v);
      return *this;
    }
    ~vector()
    {
      delete[] _start;
      _start = _finish = _endofstoage = nullptr;
    }
    T& operator[](const size_t pos)
    {
      return _start[pos];
    }
    T& operator[](const size_t pos) const
    {
      return _start[pos];
    }
    iterator begin()
    {
      return _start;
    }
    const_iterator begin() const
    {
      return _start;
    }
    reverse_iterator rbegin()
    {
      return reverse_iterator(end());
    }
    const_reverse_iterator rbegin() const
    {
      return const_reverse_iterator(end());
    }
    iterator end()
    {
      return _finish;
    }
    const_iterator end() const
    {
      return _finish;
    }
    reverse_iterator rend()
    {
      return reverse_iterator(begin());
    }
    const_reverse_iterator rend() const
    {
      return const_reverse_iterator(begin());
    }
    void reserve(size_t size)
    {
      size_t count = _finish - _start;
      size_t end = _endofstoage - _start;
      if(size >= end)
      {
        iterator tmp = new T[size];
        for(size_t i = 0;i<count;i++)
        {
          tmp[i] = _start[i];
        }
        delete[] _start;
        _start = tmp;
        _finish = _start+count;
        _endofstoage = _start+size;
      }
    }
    size_t size()
    {
      return _finish - _start;
    }
    size_t capacity()
    {
      return _endofstoage - _start;
    }
    void push_back(const T& x)
    {
      insert(end(),x);
//      if(!_start)
//      {
//        _start = new T[4];
//        _finish = _start;
//        _endofstoage = _start+4;
//      }
//      if(_finish == _endofstoage)
//      {
//        size_t end = _endofstoage - _start; 
//        size_t finish = _finish - _start;
//        T* new_start = new T[end * 2];
//        for(int i = 0;i < finish;i++)
//        {
//          new_start[i] = _start[i];
//        }
//        delete[] _start;
//        _start = new_start;
//        _finish = _start+finish; 
//        _endofstoage = _start + end*2;
//      }
//      *(_finish++) = x;
    }
    void pop_back()
    {
      erase(end()-1);
    }
    iterator insert(iterator pos,const T& x)
    {
      size_t count_pos = _start ? pos - _start : 0;
      if(_finish == _endofstoage)
      {
         size_t size = _start ? capacity()*2 : 4;
         reserve(size);
      }
      pos = _start+count_pos;
      iterator end = _finish;
      _finish++;
      while(end > pos)
      {
        *(end) = *(end-1);
        end--;
      }
      *(pos) = x;
      return pos+1;
    }
    iterator erase(iterator pos)
    {
      assert(_start);
      iterator it = pos;
      while(it < _finish-1)
      {
        *(it) = *(it+1);
        it++;
      }
      _finish--;
      return pos; 
    }


  private:
    iterator _start;
    iterator _finish;
    iterator _endofstoage;

  };
}
